package com.yc.login.web;

import com.yc.login.vo.LoginProperties;
import com.yc.login.vo.Result;
import lombok.Builder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;

@RestController
@RequestMapping
public class LoginDo {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    LoginProperties loginProperties;

    Class userClass = null;

    //定义初始化的方法
    @PostConstruct
    void init() {
        if (userClass == null) {
            try {
                userClass = Class.forName(loginProperties.getEntityClass());
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("用户类加载失败");
            }
        }
    }

    @RequestMapping("login")
    public Result login(String name, String pwd, HttpSession session) {
        if (name == null || name.trim().isEmpty()) {
            return new Result(0, "请输入用户名", null);
        }

        if (pwd == null || pwd.trim().isEmpty()) {
            return new Result(0, "请输入密码", null);
        }

        //查询用户
        String sql = "select * from %s where %s = ? and %s = ? ";
        sql = String.format(sql, loginProperties.getUserTable(),
                loginProperties.getNameColumn(),
                loginProperties.getPwdColumn());

        //查询用户的对象
        Object user = null;
        //初始化用户类
//        init();
        try {
            user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(userClass), name, pwd);
            session.setAttribute("loginedUser", user);
        } catch (DataAccessException e) {
            return new Result(0, "用户名或者密码错误", null);
        }

        return new Result(1, "登录成功", user);
    }



    @GetMapping("myinfo")
    public Result myInfo(@SessionAttribute(required = false) Object loginedUser) {
        if (loginedUser == null) {
            return new Result(0, "未登录", null);
        } else {
            return new Result(1, "已登录", loginedUser);
        }
    }

    @GetMapping("logout")
    private ModelAndView logout(HttpSession session, ModelAndView mav,
                                @RequestParam(defaultValue = "/login/index.html")String toPage) {
        session.invalidate();
        mav.setViewName("redirect:"+toPage);
        return mav;
    }

    @Resource
    private JavaMailSender mailSender;


    @GetMapping("sendTestMail")
    public void sendSimpleMail(String to,String subject,String content){
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(loginProperties.getSendMail());
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        mailSender.send(message);
    }

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    //根据用户名发送验证码邮件
    //在哪个浏览器发送邮件 就必须在哪个浏览器打开链接   跨域问题！！！
    //解决  存在redis缓存中
    @RequestMapping("sendForgetMail")
    public Result sendForgetMail(String name,HttpSession session,
                                 // 1.简单邮件  2.html邮件
                                 @RequestParam(defaultValue = "1") int type){
        if (name == null || name.trim().isEmpty()) {
            return new Result(0, "请输入用户名", null);
        }
        String sql = "select * from %s where %s = ?";
        sql = String.format(sql,loginProperties.getUserTable(),loginProperties.getNameColumn());

        //查询用户的对象
        Object user = null;
        try {
            user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(userClass), name);

            //反射  获取用户的邮箱
            Field field = user.getClass().getDeclaredField(loginProperties.getEmailColumn());
            field.setAccessible(true);
            String email = (String) field.get(user);
            //生成验证码
            String vcode = System.currentTimeMillis() + "";
            //截取后六位作为验证码
            vcode = vcode.substring(vcode.length() - 6);
            session.setAttribute("forgetVcode",vcode);

            //存redis中
            String data = redisTemplate.boundValueOps("forgetVcode").get();
            if (data == null){
                redisTemplate.boundValueOps("forgetVcode").set(vcode);
            }

            if (type == 1){
                //简单邮件
                sendSimpleMail(email,"Xxxx平台验证码","验证码为：" + vcode);
            } else{
                //html邮件
                //如果是别人的主机来访问，把localhost改为公网ip地址
                sendHTMLMail(email,"Xxx平台验证码","忘记密码，请点击<a href='http://localhost:8080/openResetHtml/" +
                        vcode + "'>链接</a>，重置密码");
            }

            return new Result(0,"验证码发送成功！",null);
        } catch (DataAccessException e) {
            e.printStackTrace();
            return new Result(0, "用户不存在", null);
        } catch (Exception e){
            e.printStackTrace();
            //发送邮件给管理员
            return new Result(0,"系统繁忙，请稍后再试",null);
        }
    }

    private void sendHTMLMail(String email, String subject,String content) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            //true表示要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message,true);
            helper.setFrom(loginProperties.getSendMail());
            helper.setTo(email);
            helper.setSubject(subject);
            helper.setText(content);
            mailSender.send(message);

        }catch (Exception e){
            throw new RuntimeException("html格式邮件发送失败"+ e);
        }
    }


    //提交新密码 携带验证码
    @RequestMapping("resetForgetPwd")
    private Result resetForgetPwd(@SessionAttribute String forgetVcode,String name,String vcode,String newPwd){
        if (name == null || name.trim().isEmpty()) {
            return new Result(0, "请输入用户名", null);
        }

        if (vcode == null || vcode.trim().isEmpty()) {
            return new Result(0, "请输入验证码", null);
        }

        if (vcode.equals(forgetVcode) == false){
            return new Result(0,"验证码错误",null);
        }

        String sql = "update %s set %s = ? where %s = ?";
        sql = String.format(sql,loginProperties.getUserTable(),loginProperties.getPwdColumn(),loginProperties.getNameColumn());

        jdbcTemplate.update(sql, newPwd, name);
        return new Result(1,"密码修改成功",null);
    }

    @PostMapping("reg")
    private Result reg(String name,String pwd1,String pwd2){
        if(name == null || name.trim().isEmpty()){
            return new Result(0, "请输入用户名", null);
        }

        if(pwd1 == null || pwd1.trim().isEmpty()){
            return new Result(0, "请输入密码", null);
        }

        if(pwd2 == null || pwd2.trim().isEmpty()){
            return new Result(0, "请确认密码", null);
        }

        if (pwd1.equals(pwd2) == false){
            return new Result(0,"两次密码不一致",null);
        }


        String sql = "insert into %s (%s,%s) values (?,?)";
        sql = String.format(sql,loginProperties.getUserTable(),loginProperties.getNameColumn(),loginProperties.getPwdColumn());

        jdbcTemplate.update(sql, name, pwd1);
        return new Result(1,"注册成功",null);
    }



    @GetMapping("/openResetHtml/{vcode}")
    private ModelAndView openResetHtml(@PathVariable String vcode,ModelAndView mav){
        String forgetVcode = redisTemplate.boundValueOps("forgetVcode").get();
        if (forgetVcode == null){
            mav.setViewName("redirect:/错误的页面(验证码错误).html");
            return mav;
        }
        if (forgetVcode.equals(vcode)){
            mav.setViewName("redirect:/login/reset.html");
        }else{
            mav.setViewName("redirect:/错误的页面(验证码错误).html");
        }
        return mav;
    }

    //用户登陆后修改密码
    @PostMapping("updatePwd")
    private Result updatePwd(String pwd){
        return null;
    }


}
